package com.kaili.db.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.kaili.client.service.ICustomerService;
import com.kaili.client.service.ILoginUserInfoService;
import com.kaili.client.service.ISubEwbGenerator;
import com.kaili.common.OperationType;
import com.kaili.common.exception.BaseExcept;
import com.kaili.common.stock.StockInfoBean;
import com.kaili.common.util.SnowflakeIdFactory;
import com.kaili.db.mapper.HsOptEwbMapper;
import com.kaili.db.service.*;
import com.kaili.pojo.dto.ewb.EwbAddDTO;
import com.kaili.pojo.dto.ewb.GoodsDetailAddBean;
import com.kaili.pojo.entity.*;
import com.kaili.pojo.vo.*;
import com.kaili.utils.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cgm
 * @since 2018-05-08
 */
@Service
@Transactional
public class HsOptEwbServiceImpl extends ServiceImpl<HsOptEwbMapper, HsOptEwb> implements IHsOptEwbService {

    @Autowired
    ILoginUserInfoService loginUserInfoService;

    @Autowired
    ICustomerService customerService;

    @Autowired
    IHsOptGoodsDetailService goodsDetailService;

    @Autowired
    IHsOptEwbAppointService ewbAppointService;

    @Autowired
    IHsOptQueryService queryService;

    @Autowired
    IHsEwbSubStockService subStockService;

    @Autowired
    IHsEwbSubService ewbSubService;

    @Autowired
    ISubEwbGenerator subEwbGenerator;

    @Autowired
    HsOptEwbMapper hsOptEwbMapper;

    @Autowired
    IHsEwbsStowageService stowageService;

    @Override
    public int doSignByEwb(String ewb) {
        Wrapper<HsOptEwb> wrapper = new EntityWrapper<>();
        wrapper.where("ewb_no={0}", ewb);
        HsOptEwb ewb1 = new HsOptEwb();
        ewb1.setEwbNo(ewb);
        ewb1.setIsSign(1);
        return baseMapper.update(ewb1, wrapper);
    }

    @Override
    public HsOptEwb getEWbByEwbNo(String ewb) {
        Wrapper<HsOptEwb> wrapper = new EntityWrapper<>();
        wrapper.where("ewb_no={0}", ewb);
        List<HsOptEwb> list = baseMapper.selectList(wrapper);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public boolean isSign(String ewb) {
        Map search = new HashMap();
        search.put("ewb_no", ewb);
        search.put("is_sign", 1);
        List<HsOptEwb> lst = baseMapper.selectByMap(search);
        if (lst != null && lst.size() > 0) {
            return true;
        }
        return false;
    }

    @Override
    public int doAddEwb(EwbAddDTO addBean) throws BaseExcept {
        boolean isAdd = false;
        String operationId = addBean.getOperationId();
        String ewbNo = addBean.getEwbNo();
        if(operationId == null){
            isAdd = true;
        }
        Integer loginUserId = loginUserInfoService.getLoginUserId();
        Integer loginSiteId = loginUserInfoService.getLoginSiteId();
        Integer totalPiece = 0;

        HsOptEwb ewb  = new HsOptEwb();
        BeanUtils.copyProperties(addBean,ewb);

        if(isAdd){
            operationId = String.valueOf(SnowflakeIdFactory.getNextId());
            ewb.setCreatedTime(DateUtils.getCurrentDate());
            ewb.setCreatedBy(loginUserId);
            ewb.setSendSiteId(loginSiteId);
            ewb.setOperationId(operationId);

            baseMapper.insert(ewb);

            //预约号不为空则说明该单是选择预约登记的,开单后关联预约单和运单
            if(StringUtils.isNotEmpty(addBean.getAppointNo())){
                HsOptEwbAppoint ewbAppoint =  new HsOptEwbAppoint();
                ewbAppoint.setAppointNo(addBean.getAppointNo());
                ewbAppoint.setIsBilling(1);//已开单
                ewbAppoint.setEwbNo(ewbNo);
                ewbAppoint.setIsHandle(1);//已处理
                ewbAppointService.updateById(ewbAppoint);
            }
        }else{
            ewb.setModifiedBy(loginUserId);
            ewb.setModifiedTime(DateUtils.getCurrentDate());
            baseMapper.updateById(ewb);

            delete(ewbNo);
        }

        List<GoodsDetailAddBean> goodsDetailAddList =  addBean.getGoodsDetailList();
        List<HsOptGoodsDetail> goodsDetailList =  new ArrayList<HsOptGoodsDetail>();
        List<HsEwbSub> ewbSubList = new ArrayList<>();
        List<String> subList = subEwbGenerator.getSubEwb(ewbNo,ewb.getTotalPiece());
        int count = 0;
        for (int i = 0; i < goodsDetailAddList.size(); i++) {
            GoodsDetailAddBean goodsDetailAdd = goodsDetailAddList.get(i);
            HsOptGoodsDetail goodsDetail = new HsOptGoodsDetail();
            BeanUtils.copyProperties(goodsDetailAdd , goodsDetail);
            goodsDetail.setCreatedTime(DateUtils.getCurrentDate());
            goodsDetail.setEwbNo(ewbNo);
            goodsDetail.setGoodsId(SnowflakeIdFactory.getNextId());
            goodsDetailList.add(goodsDetail);

            Integer piece = goodsDetailAdd.getPiece();
            totalPiece+=piece;
            String avgWeight = String.format("%.2f",goodsDetailAdd.getWeight().doubleValue()/piece);
            String avgVol = String.format("%.2f",goodsDetailAdd.getVol().doubleValue()/piece);
            for(int j=0; j<goodsDetailAdd.getPiece();j++){
                HsEwbSub ewbSub = new HsEwbSub();
                ewbSub.setEwbNo(ewbNo);
                ewbSub.setSubEwb(subList.get(count));
                ewbSub.setGoodsType(goodsDetail.getPackTypeCode());
                ewbSub.setVol(BigDecimal.valueOf(Double.valueOf(avgVol)));
                ewbSub.setWeight(BigDecimal.valueOf(Double.valueOf(avgWeight)));
                ewbSub.setCalcWeight(BigDecimal.valueOf(Double.valueOf(avgWeight)));
                ewbSubList.add(ewbSub);
                count++;
            }
        }

        //插入运单货物明细
        goodsDetailService.insertBatch(goodsDetailList);

        //插入子单库存
        StockInfoBean bean = new StockInfoBean();
        bean.setEwbNo(ewb.getEwbNo());
        bean.setSiteId(loginSiteId);
        bean.setSize(totalPiece);
        subStockService.ewbAddStock(bean);

        //插入主单-子单关联表
        ewbSubService.insertBatch(ewbSubList);

        //插入快件跟踪记录
        HsOptQuery optQuery = new HsOptQuery();
        optQuery.setEwbNo(ewb.getEwbNo());
        optQuery.setStep(OperationType.BILLING);//1开单  2配载  3发车  4在途  5到车  6派件  7签收
        optQuery.setOperationId(operationId);
        optQuery.setOperationTime(addBean.getEwbDate());
        optQuery.setOperator(loginUserId);
        optQuery.setOperationSiteId(loginSiteId);
        queryService.insert(optQuery);

        //托运开单调用财务存储过程 p_fin_opt_ewb_input生成账单
        JSONArray array = new JSONArray();
        JSONObject obj = new JSONObject();
        obj.put("operation_id",operationId);
        obj.put("send_customer_id",ewb.getSendCustomerId());//寄件人ID
        obj.put("send_site_id",ewb.getSendSiteId());//寄件网点id
        obj.put("total_freight_charge",ewb.getTotalFreightCharge());//运费
        if(ewb.getPickGoodsModeId().intValue() == 105){//派送
            obj.put("send_charge",ewb.getSendCharge());//派送费
            obj.put("self_charge",0);//自提费
        }else if(ewb.getPickGoodsModeId().intValue() == 106){//自提
            obj.put("send_charge",0);//派送费
            obj.put("self_charge",ewb.getSendCharge());//自提费
        }
        obj.put("dob_insurance_fee",ewb.getDobInsuranceFee());//保费
        obj.put("delivery_charge",ewb.getDeliveryCharge());//接货费
        obj.put("business_charge",ewb.getBusinessCharge());//业务费
        obj.put("receive_send_cod_charge",ewb.getReceiveSendCodCharge());//代收货款手续费

        if(isAdd){
            obj.put("created_by",ewb.getCreatedBy());//创建人
            obj.put("created_time",DateUtils.dateToStrLong(ewb.getCreatedTime()));//创建时间
            obj.put("operate_type",1);//操作类型，1表示新增 2表示修改 3表示删除
        }else{
            obj.put("created_by",ewb.getModifiedBy());//修改人
            obj.put("created_time",DateUtils.dateToStrLong(ewb.getModifiedTime()));//修改时间
            obj.put("operate_type",2);//操作类型，1表示新增 2表示修改 3表示删除
        }

        obj.put("ewb_no",ewb.getEwbNo());//运单号
        obj.put("remark",ewb.getRemark());//备注
        array.add(obj);
        Map<String,Object> map = new HashMap<>();
        map.put("v_param",array.toJSONString());
        baseMapper.callEwbInputFinProduce(map);
        return 0;
    }

    @Override
    public void deleteEwbNo(String ewbNo){
        //删除运单
        Wrapper<HsOptEwb> optEwbWrapper = new EntityWrapper<>();
        optEwbWrapper.where("ewb_no ={0}", ewbNo);
        baseMapper.delete(optEwbWrapper);

        delete(ewbNo);
    }

    private void delete(String ewbNo){
        //删除运单货物明细
        Wrapper<HsOptGoodsDetail> optGoodsDetailWrapper = new EntityWrapper<>();
        optGoodsDetailWrapper.where("ewb_no ={0}", ewbNo);
        goodsDetailService.delete(optGoodsDetailWrapper);

        //删除主单-子单关联表
        Wrapper<HsEwbSub> ewbSubWrapper = new EntityWrapper<>();
        ewbSubWrapper.where("ewb_no ={0}", ewbNo);
        ewbSubService.delete(ewbSubWrapper);

        //删除子单库存
        Wrapper<HsEwbSubStock> ewbSubStockWrapper = new EntityWrapper<>();
        ewbSubStockWrapper.where("ewb_no ={0}", ewbNo);
        subStockService.delete(ewbSubStockWrapper);

        //删除快件跟踪记录
        Wrapper<HsOptQuery> optQueryWrapper = new EntityWrapper<>();
        optQueryWrapper.where("ewb_no ={0}", ewbNo);
        queryService.delete(optQueryWrapper);
    }

    @Override
    public Page<EwbQueryVO> queryEwbList(Page<EwbQueryVO> page, Map search) {
        return page.setRecords(baseMapper.queryEwbList(page,search));
    }

    @Override
    public EwbSummaryVO queryEwbSummary(Map search) {
        return baseMapper.queryEwbSummary(search);
    }

    @Override
    public List<EwbQueryVO> queryEwbList(Map search) {
        return baseMapper.queryEwbList(search);
    }

    @Override
    public List<EwbQueryVO> queryEwbListByStowageNo(Map search) {
        return baseMapper.queryEwbListByStowageNo(search);
    }

    @Override
    public List<EwbQueryVO> queryUnLoadingEwbList(Map search) {
        return baseMapper.queryUnLoadingEwbList(search);
    }

    @Override
    public List<DailyDeliveryStatisticsVO> queryStatistics(Map search) {
        return baseMapper.queryStatistics(search);
    }

    @Override
    public Page<DailyDeliveryEwbVO> queryDailyDeliveryEwbList(Page<DailyDeliveryEwbVO> page,Map search) {
        return page.setRecords(baseMapper.queryDailyDeliveryEwbList(page,search));
    }

    @Override
    public Page<ServiceReportVO> queryServiceStatistics(Page<ServiceReportVO> page, Map search) {
        return page.setRecords(baseMapper.queryServiceStatistics(page,search));
    }

    @Override
    public boolean isEwbNoRepeat(String ewbNo) {
        Wrapper<HsOptEwb> wrapper = new EntityWrapper<>();
        wrapper.where("ewb_no={0}", ewbNo);
        int ewbCount = baseMapper.selectCount(wrapper);
        if(ewbCount>0){
            return true;
        }

        return false;
    }

    @Override
    public Integer getInfoByEwbNo(Map map) {
        return hsOptEwbMapper.getInfoByEwbNo(map);
    }

    @Override
    public Integer getInfoByEwbNoCount(Map map) {
        return hsOptEwbMapper.getInfoByEwbNoCount(map);
    }

    @Override
    public Integer selectCompanyId(Integer siteId) {
        return hsOptEwbMapper.selectCompanyId(siteId);
    }

    @Override
    public Double selectMaxVolume(String companyId) {
        return hsOptEwbMapper.selectMaxVolume(companyId);
    }

    @Override
    public Double selecthighVolume(String ewbNo,Date dateTime) {
        return hsOptEwbMapper.selecthighVolume(ewbNo,dateTime);
    }

    @Override
    public Integer selectDriver(String operationId) {
        return hsOptEwbMapper.selectDriver(operationId);
    }

    @Override
    public int updateBatch(Map search){
        hsOptEwbMapper.updateBatch(search);
        return 0;
    }

    @Override
    public List<BaseDict> selectDict() {
        return hsOptEwbMapper.selectDict();
    }

    @Override
    public int addCustomer(CustomerVO customer) {

        return hsOptEwbMapper.addCustomer(customer);
    }

    @Override
    public String getMaxCustomerCode() {
        String str = hsOptEwbMapper.getMaxCustomerCode();
        if (StringUtils.isEmpty(str)) {
            str = "0000";
        }
        String result = String.valueOf(Integer.valueOf(str)+1);
        if (result.length() == 1){
            result = "000" + result;
        }else if (result.length() == 2){
            result = "00" + result;
        }else if (result.length() == 3){
            result = "0" + result;
        }
        return result;
    }


    @Override
    public List<Map<String, Object>> getSettleMethod() {
        return hsOptEwbMapper.selectSettleMethod();
    }

    @Override
    public List<Map<String, Object>> getPayMethod() {
        return hsOptEwbMapper.selectPayMethod();
    }

}
